console.log(typeof null) // object
function c () {}
console.log(typeof c) //function
var d = /^a/
console.log(typeof d) // object
var message // 说明声明但未赋值的变量与未声明的变量是有区别的
try {
  console.log('message', message)
  console.log('age', age)
} catch (err) {
  console.log(err)
}
try {
  console.log('typeof message', typeof message) // undefined
  console.log('typeof age', typeof age) //undefined
} catch (err) {
  console.log(err)
}
try {
  console.log('只判断值相等null == undefined', null == undefined) // true
  console.log('判断值与类型都相等 null === undefined', null === undefined) // false
} catch (error) {
  console.log(error)
}
try {
  console.log(Boolean(Infinity)) // true
  console.log(Boolean(NaN)) //false
  console.log(Boolean(-Infinity)) //true
  console.log(Boolean(-100)) //true
  console.log(Boolean(0)) //false
  console.log(Boolean(new Array())) //true
  console.log(Boolean(null)) //false
  console.log(Boolean(undefined)) // false
} catch (error) {
  console.log(err)
}
console.log('MAX_VALUE', Number.MAX_VALUE)
console.log('MIN_VALUE', Number.MIN_VALUE)
console.log('0/0', 0/0) //  NaN
console.log('100/0', 100/0) // Infinity
console.log('-100/0', -100/0) // -Infinity
console.log('typeof NaN', typeof NaN) // number
// isNaN()
console.log('NaN', isNaN(NaN)) // true
console.log('boolean', isNaN(true)) // false
console.log('string', isNaN('blue')) //true
console.log('NumberString', isNaN('10')) //false
// 数值转换
// Number
console.log(Number(true)) // 1
console.log(Number(false))// 0
console.log(Number(33)) // 33
console.log(Number(011)) // 9 按八进制规则转化
console.log(Number('011')) // 11 字符串是却没有按照8进制规则转化，而只是忽略了前导0
console.log(Number(null)) // 0
console.log(Number('null')) //  NaN
console.log(Number(undefined)) // NaN
console.log(Number('undefined')) // NaN  not a number
console.log(Number('123')) // 123
console.log(Number(0xf)) // 15 // 16进制的话不管是字符串还是数字都会按照16进制的规则进行转化
console.log(Number('0xf')) // 15
console.log(Number('')) // 0
console.log(Number('123abc')) // NaN
// parseInt转化字符串为数值
// parseInt转化字符串为数字 问题集中在解析8进制上，ECMAscript 3跟ECMAscript5存在区别，
// 3会将前导0作为8进制的标识，5版本会直接忽略前导0。为了避免这种情况，需要在解析的时候，给parseInt
// 加上第二个参数作为转化的技术
console.log(parseInt('+10')) //10
console.log(parseInt('10.22')) //10
console.log(parseInt('1234blue')) // 1234
console.log(parseInt('011')) // 11
console.log(parseInt('011', 8)) // 9
console.log(parseInt('070')) // 70
console.log(parseInt('070', 8)) // 56
console.log(parseInt('0xf')) // 15
console.log('+++++++++++++++++++++++++++++++++')
// parseFloat转化字符串为数值
// 1.解析到无效的浮点数字字符为止
// 2.始终忽略字符串的前导0
// 3.parseFloat始终解析十进制，但16进制格式的字符串始终解析为0
// 4.如果字符串包含的是一个可解析为整数的的数。parseFloat会返回整数
console.log(parseFloat('1234blue')) // 1234
console.log(parseFloat('0xf')) // 0
console.log(parseFloat('011')) // 11
console.log(parseFloat('2.0')) // 2
console.log(parseFloat('2.1100')) //2,11
console.log(parseFloat('2.1100.22')) //2.11
console.log(parseFloat('2.1100abc'))// 2.11
console.log(parseFloat('2.11')) // 2.11
console.log(parseFloat('2.11e7')) // 21100000
console.log(parseFloat('02.11e7'))// 21100000
// String类型
// toString()方法，几乎每个值都有
var t = true
var n = 10
var s = 'lee'
var nul = null
var undef = undefined
try {
  console.log('Boolean', t.toString()) // true
  console.log('Number 10', n.toString())// 10
  console.log('parseInt 8', parseInt(n, 8))// 8 8进制中哪个数表示10
  console.log('Number 8', n.toString(8)) // 12 以八进制的形式输出， 10在八进制中是多少
  console.log('String', s.toString()) // lee
  console.log('Null', nul.toString()) // null 无toString方法  直接报错
  console.log('Undefined', undef.toString())// undefined也无toString方法
} catch (error) {
  console.log(error)
}

// String()方法
try {
  console.log(String(t)) // true
  console.log(String(nul)) //null
  console.log(String(undef))//undefined
} catch (error) {
  console.log(error)
}
console.log('ObjectObjectObjectObjectObjectObjectObjectObjectObject')
function Box() {
  this.age = 26
  this.color = 'blue'
}
// 所有对象都会从它的原型上继承一个 constructor 属性
var box = new Box() // 
var desk = new Box()
Box.prototype = {
  run: function() {
    console.log('年龄: ' + this.age + " 颜色 " + this.color)
  }
}
box.taller = 100
box.__proto__.longer = 200
try {
  console.log('未重写原型', box.__proto__) // longer: 200, constructor: function Box(){}
  console.log('constructor', box.constructor) // function Box() {}
  console.log('constructor.toString()', box.constructor.toString()) // function Box() {}
  console.log('constructor.toLocaleString()', box.constructor.toLocaleString())
  console.log('constructor.valueOf()', box.constructor.valueOf())
  console.log(desk.taller) // undefined   只是将属性添加到实例上去了，没办法映射到另一个对象
  console.log(desk.longer) // 200 添加到原型上了，就可以继承了
  console.log(box.hasOwnProperty('age')) // true  判断实例中是否有属性
  console.log(box.hasOwnProperty('run')) // false
} catch (error) {
  console.log(error)
}

var monkey = {}
Object.defineProperty(monkey, 'born', {
  value: '1993 07 26',
  writable: true,
  configurable: true,
  enumerable: false // 不可被枚举
})
try {
  console.log('monkey', monkey)
  console.log('propertyIsEnumerable', monkey.propertyIsEnumerable('born')) // false
} catch (e) {
  console.log(e)
}